上一篇我們詳細介紹了 VGG 16 模型的使用方法,現在,我們就來應用它來進行照片比對,根據照片內主體的相似度(Visual Similarity)判斷,找出相關的照片,例如,我們要在 3D 模型網站搜尋『卡通人物』模型,我們可以輸入一張照片,程式就可以幫我們找出相似的 3D 模型,有興趣的讀者想了解詳情可參閱 Using Keras' Pretrained Neural Networks for Visual Similarity Recommendations。
圖. 照片比對,輸入最上面一張圖,找出下面類似的模型,圖片來源:Using Keras' Pretrained Neural Networks for Visual Similarity Recommendations
本程式名稱vgg16_vs.py,可在這裡找到,先準備一組照片檔,內含幾類照片,例如,狗、貓、熊等,放在程式所在目錄下的images子目錄,然後執行下列指令:
python vgg16_vs.py 1
vgg16_vs.py 程式需要一個參數,是images子目錄下第N張照片(即上面指令的 1,注意,陣列索引起始值是0)。執行結果會顯示最相似的兩張照片,我實驗結果相當好,可以找出不同姿勢的動物,相似度的判斷非常準確。
from keras.applications.vgg16 import VGG16
from keras.preprocessing import image
from keras.applications.vgg16 import preprocess_input, decode_predictions
import numpy as np
import os
import sys
# 計算相似矩陣
def cosine_similarity(ratings):
sim = ratings.dot(ratings.T)
if not isinstance(sim, np.ndarray):
sim = sim.toarray()
norms = np.array([np.sqrt(np.diagonal(sim))])
return (sim / norms / norms.T)
def main():
# 自 images 目錄找出所有 JPEG 檔案
y_test=[]
x_test=[]
for img_path in os.listdir("images"):
if img_path.endswith(".jpg"):
img = image.load_img("images/"+img_path, target_size=(224, 224))
y_test.append(img_path[0:4])
x = image.img_to_array(img)
x = np.expand_dims(x, axis=0)
if len(x_test) > 0:
x_test = np.concatenate((x_test,x))
else:
x_test=x
# 轉成 VGG 的 input 格式
x_test = preprocess_input(x_test)
# include_top=False,表示會載入 VGG16 的模型,不包括加在最後3層的卷積層,通常是取得 Features (1,7,7,512)
model = VGG16(weights='imagenet', include_top=False)
# 萃取特徵
features = model.predict(x_test)
# 計算相似矩陣
features_compress = features.reshape(len(y_test),7*7*512)
sim = cosine_similarity(features_compress)
# 依命令行參數,取1個樣本測試測試
inputNo = int(sys.argv[1]) # tiger, np.random.randint(0,len(y_test),1)[0]
top = np.argsort(-sim[inputNo], axis=0)[1:3]
# 取得最相似的前2名序號
recommend = [y_test[i] for i in top]
print(recommend)
if __name__ == "__main__":
main()
cosine_similarity 函數:這是程式最重要的部分,將images目錄內的每一張照片轉成特徵向量,再兩兩作比較,利用 cosine 函數計算兩個特徵向量的角度,越接近 1,表示越相似,這幾行程式碼來自Using Keras' Pretrained Neural Networks for Visual Similarity Recommendations。
main 函數:
由於相似度矩陣要倆倆比較,如果圖檔很多,執行就要等一下了,另外,我一開始是使用 keras 現成資料集 CIFAR100 small image ,準確率一直很差,我以為程式寫錯了,後來才發覺 CIFAR100 圖像素只有 32 x 32,太小了,不適合 VGG 訓練模型,所以,讀者找圖時要找像素大一點(224x224以上)的圖檔測試。
這個程式可應用在哪裡呢?
現在每個人一支手機在手,都會拍了很多照片,我們如果要從幾千張照片中找出與某個人有關的照片,就可以用本篇介紹的建模方式,自動比對就搞定了。
幾年前參加一場演講,講師談到『如何評估NBA球賽的廣告看板效益』,他們計算整段轉播影片中出現多少次某個廣告看板,藉此判斷是否符合成本效益? 以及放在哪一個位置的看板曝光率最高,當時覺得很神奇,現在,看完這一篇,讀者也可以做得到了,只要利用VGG模型,將看板、影片放入訓練資料,就可以找到有出現看板的影片了。
另類的商品推薦(cross sale/Up sale):例如我們在電子商務網站上瀏覽某一項商品時,網站常常會推薦一些相關商品給我們,可能是熱銷或搭配使用的商品,譬如瀏覽電腦主機,系統就會推薦其他型號或廠牌的主機,推薦的商品通常是由後台依照產品分類、使用者偏好、促銷活動及商品銷售狀況統計出來的,如果用這個程式,要找到其他相似外型的商品就簡單多了。
罪犯追蹤:現在街頭監視器滿街都是,犯罪現場常能拍到嫌疑犯身影,若要追查行蹤,聽說刑警必須緊盯螢幕,看錄影帶一整天,才能找出嫌疑犯的藏匿處,若是能應用本篇介紹的演算法應用,也許在短時間內,就可以找到有嫌疑犯身影的相關影片了。
這次我們學會如何使用 Keras Applications,作出實際可用的應用,下次,我們就來討論另一個應用『風格轉換』(Style Transfer),讓人人都可以變成畢卡索、梵谷,今天剛好看到一個新聞『催生全球首位AI繪師Andy,美圖搶攻人工智慧卻面臨一大挑戰』,這個主題很夯喔。
您好,想請問執行後出現
Traceback (most recent call last):
File "vgg16_vs.ipynb", line 7, in
"collapsed": false
NameError: name 'false' is not defined
是因為python的版本不同嗎?
應該是 Keras 版本的問題,要安裝 keras 2.2,指令如下:
pip install keras=2.2.0
您好,當我在執行inputNo = int(sys.argv[1])這行程式碼時,會出現錯誤list index out of range,想請問要怎麼解決,經上網查詢獲得以下資訊:
sys.argv[]是用來獲取命令行參數的,sys.argv[0]表示代碼本身文件路徑,所以參數從1開始,從cmd輸入......
但我程度太差,看不太懂
就是該程式執行時,須帶一參數,如下:
python vgg16_vs.py 1
1: 表示第一張,可參考『實作』說明
收穫良多 感謝
終於感覺理論可以應用
cosine_similarity 可以這樣在高維空間使用
終於一步一步了解了更多cnn應用相關延伸
謝謝
讚,分享的動力+1。